import { HttpService, Injectable } from '@nestjs/common';
import { MredisService } from '@app/mredis';
import { fileHost } from '@app/qiniu/utils/config';
import qiniu = require('qiniu');
import fse = require('fs-extra');
import { join } from 'path';

const accessKey = 'm1syJtZt97vSWT6sPrIce_dTRACwFtBViffPbIVA';
const secretKey = '0fdH7wRdY2F7gdTJeqA74JqT0uA2xM1SvOI8_aCE';

@Injectable()
export class QiniuService {
  constructor(
    private readonly mredisService: MredisService,
    private readonly httpService: HttpService,
  ) {}

  private async getToken() {
    const mac = new qiniu.auth.digest.Mac(accessKey, secretKey);

    // 上传凭证
    const putPolicy = new qiniu.rs.PutPolicy({
      scope: 'file-mi',
      expires: 60 * 60,
    });

    let uploadToken = await this.mredisService.get('qiniu-token');
    if (!uploadToken) {
      uploadToken = putPolicy.uploadToken(mac);
      await this.mredisService.set('qiniu-token', uploadToken, 60 * 60);
    }
    return uploadToken;
  }

  // 上传文件
  async uploadFile(
    keyPath: string,
    stream: NodeJS.ReadableStream,
    option?: qiniu.form_up.PutExtra,
  ): Promise<any> {
    const config = new qiniu.conf.Config({ zone: qiniu.zone.Zone_z0 });
    const formUploader = new qiniu.form_up.FormUploader(config);
    const putExtra = option || new qiniu.form_up.PutExtra();
    const token = await this.getToken();

    // return new Promise((resolve, reject) => {
    //   formUploader.put(token, keyPath, body, putExtra, (err, body, info) => {
    //     err ? reject(err) : resolve(body);
    //   });
    // });

    return new Promise((resolve, reject) => {
      formUploader.putStream(
        token,
        keyPath,
        stream,
        putExtra,
        (err, body, info) => {
          err ? reject(err) : resolve(body);
        },
      );
    });
  }
  // 获取文件地址
  getFileUrl(keyPath: string): string {
    let mac = new qiniu.auth.digest.Mac(accessKey, secretKey);
    let config = new qiniu.conf.Config();
    let bucketManager = new qiniu.rs.BucketManager(mac, config);
    // 公开空间访问链接
    let publicDownloadUrl = bucketManager.publicDownloadUrl(fileHost, keyPath);
    // console.log(publicDownloadUrl);
    return publicDownloadUrl;
  }
  // 下载文件
  downloadFile(url: string): Promise<string> {
    return new Promise((resolve, reject) => {
      this.httpService
        .post<ArrayBuffer>(url, null, {
          timeout: 10 * 60 * 1000,
          responseType: 'arraybuffer',
        })
        .toPromise()
        .then(res => {
          // 创建文件夹
          let pathFile = join(__dirname, 'tmp', 'android.apk');
          fse.ensureFileSync(pathFile);

          // 文件地址
          fse.writeFile(pathFile, res.data, err => {
            err ? reject(err) : resolve(pathFile);
          });
        })
        .catch(err => {
          reject(err);
        });
    });
  }
}
